package com.lry.jvm.instructions.refrences;

import com.lry.jvm.instructions.base.ClassInit;
import com.lry.jvm.instructions.base.Index16Instruction;
import com.lry.jvm.instructions.base.MethodInvoke;
import com.lry.jvm.rtda.Frame;
import com.lry.jvm.rtda.heap.JClass;
import com.lry.jvm.rtda.heap.JMethod;
import com.lry.jvm.rtda.heap.MethodRef;
import com.lry.jvm.rtda.heap.RuntimeConstantPool;
import com.lry.jvm.util.Util;

public class invokestatic extends Index16Instruction {
    @Override
    public byte getOpCode() {
        return (byte) 0xb8;
    }

    @Override
    public void execute(Frame frame) {
        RuntimeConstantPool rcp = frame.getMethod().getJClass().getConstantPool();
        MethodRef methodRef = (MethodRef) rcp.getConstant(index);
        JMethod method = methodRef.resolvedMethod();

        JClass methodClass = method.getJClass();
        if(!methodClass.isInitStarted()){
            //回退pc，结束当前指令运行
            frame.revertNextPc();
            //初始化clinit
            ClassInit.initClass(frame.getThread(),methodClass);
            //结束当前指令运行
            return;
        }

        if(!method.isStatic()){
            Util.panic("java.lang.IncompatibleClassChangeError");
        }
        MethodInvoke.invokeMethod(frame,method);
    }
}
